<template>
  <view class="server-cascader" v-if="data?.list?.length">
    <scroll-view v-for="(item, idx) in data?.list" class="menu" scroll-y>
      <view
        class="item"
        :key="idx"
        @click="selectMenu(idx)"
        :class="{ selected: data?.activeIdx == idx }"
      >
        <text class="text title">{{ item[0]?.name }}</text>
        <view
          class="value"
          @click="toShow(item[0])"
          :class="{ isred: item[0]?.isShow }"
          v-if="item.length > 6"
        >
          {{ item[0]?.isShow ? "收起" : "展开" }}
          <image
            class="iconfont"
            :src="item[0]?.isShow ? iconFilterU : iconFilterD"
          ></image>
        </view>
      </view>
      <view class="search">
        <image class="icon" src="@/assets/icon-search-placeholder-fill.png" />
        <less-input
          class="search-input"
          placeholder="搜索选项"
          v-model="item[0].keywords"
          @update:model-value="emitKeywordChanged(item, item[0].keywords || '')"
          :maxlength="10"
        />
      </view>
      <view class="empty" v-if="isLen(item)">
        <image class="image" src="@/assets/search-empty.png" />
        <view class="text">
          没有与“
          <view class="keywords">{{ item[0].keywords }}</view>
          ”匹配的结果
        </view>
      </view>
      <view
        class="grid-select search-select"
        :style="{
          gridTemplateColumns: `repeat(${3}, 1fr)`,
        }"
        v-if="item[0].searchList.length > 0"
      >
        <view
          v-for="option in item[0].searchList"
          @click="selectOption(option, item, idx)"
          :class="{
            selected: option.selected,
          }"
          class="option"
        >
          {{ option?.value }}
        </view>
      </view>
      <scroll-view class="content" scroll-y>
        <view class="list">
          <view
            class="item"
            :class="{
              selected: allList[idx],
            }"
            @click="selectItem(undefined, idx, item)"
          >
            <text class="text">全部</text>
          </view>
          <view
            class="item"
            v-for="(node, i) in item"
            :key="node.id"
            @click="selectItem(node, idx, item, i)"
            :class="{
              selected: node.selected,
            }"
            v-show="item[0]?.isShow || i < 5"
          >
            <text class="text">{{ node?.value }}</text>
          </view>
        </view>
      </scroll-view>
    </scroll-view>
  </view>
</template>

<script lang="ts" setup>
import type { GameRegion } from "@/types/index";
import { computed, onMounted, reactive, watch, ref } from "vue";
import LessInput from "@/components/less-input/index.vue";
import { useDebounce } from "@/hooks/core/useDebounce";
import iconFilterD from "@/assets/icon-filter-d.svg";
import iconFilterU from "@/assets/icon-filter-u.svg";

const props = defineProps<{
  options: GameRegion[];
  modelValue: GameRegion[];
}>();

const emits = defineEmits<{
  (event: "update:modelValue", value: GameRegion[]): void;
  (event: "finish"): void;
  (event: "keywordChanged");
}>();

const data = reactive<{
  list?: GameRegion[][];
  activeIdx: number;
}>({
  list: undefined,
  activeIdx: 0,
});
const searchList = ref([]) as any;
const keywords = ref("");
const searchOptions = computed(() => {
  if (searchList.value.length > 0 && !keywords.value.trim()) {
    return [];
  }
  return searchList.value.filter((e: any) => e?.value.includes(keywords.value));
});

const activeItem = computed(() => {
  return data.list?.[data.activeIdx];
});

const isLen = (item: any) => {
  if (Array.isArray(item) && item.length > 0) {
    if (item[0]?.keywords?.length > 0 && item[0]?.searchList?.length == 0)
      return true;
    else return false;
  }
  return false;
};

const [emitKeywordChanged] = useDebounce((item: any, keywords: string) => {
  if (!keywords) {
    item[0].searchList = [];
    return;
  }
  item[0].searchList = item.filter((e: any) => e?.value.includes(keywords));
}, 300);

const selectOption = (option: any, item: any, idx: number) => {
  const id = item.findIndex((e: any) => e.id == option.id);
  selectItem(item[id], idx, item, id);
};
const allList = ref([]) as any;
setTimeout(() => {
  console.log(props.options);
}, 1000);

watch(
  () => props.options,
  (e) => {
    if (props.options) {
      data.list = [
        props.options.map((e) => {
          return {
            ...e,
            selected: false,
            isShow: false,
            keywords: "",
            searchList: [],
          };
        }),
      ];
      data.list.map((e) => {
        allList.value.push(false);
      });
      resumeDisplay();
    } else {
      data.list = [];
    }
  }
);

const toShow = (attr: any) => {
  attr.isShow = !attr.isShow;
};

onMounted(() => {
  if (props.options) {
    data.list = [
      props.options.map((e) => {
        return {
          ...e,
          selected: false,
          isShow: false,
          keywords: "",
          searchList: [],
        };
      }),
    ];
    resumeDisplay();
  } else {
    data.list = [];
  }
});

const resumeDisplay = () => {
  props.modelValue.forEach((v, idx) => {
    const temp = data.list?.[idx]?.find((e) => e.id == v.id);
    if (temp?.children) {
      data.list?.push(temp.children);
      data.activeIdx = idx + 1;
    }
  });
};

const selectMenu = (idx: number) => {
  data.activeIdx = idx;
};

const setModelValue = (values: GameRegion[]) => {
  emits("update:modelValue", [...values]);
};

const selectMenuList = ref([]) as any; //当前查看的区服索引

const clearItem = () => {
  if (data.list) {
    data.list.forEach((e: any) => {
      e.map((item: any) => (item.selected = false));
    });
  }
};

const parseRadioOptions = (attr: any) => {
  try {
    console.log(attr);
    const options = JSON.parse(attr.attr_value);
    if (Array.isArray(options)) {
      return options.map((e) => ({
        label: e.name,
        value: e.name,
      }));
    }
    return [];
  } catch (error) {
    return [];
  }
};

const selectItem = (
  item?: GameRegion,
  index?: number | undefined,
  arr?: any,
  chI?: number | undefined
) => {
  if (item && index !== undefined) {
    //高亮
    if (!item.selected) {
      arr.map((e: any) => (e.selected = false));
      item.selected = true;
    } else {
      item.selected = false;
    }
    // 是否重复点击
    if (
      (selectMenuList.value[index] && selectMenuList.value[index] == chI) ||
      selectMenuList.value.filter((e: any) => e == index).length > 1
    ) {
      return;
    }
    //给定索引
    selectMenuList.value[index] = chI;
    allList.value[index] = false;
    // 保存值
    const values = [...props.modelValue].filter((e) => e);
    values.splice(index);
    values.push(item);
    setModelValue(values);
    // 更新菜单
    if (data.list && Array.isArray(item.children) && item.children.length > 0) {
      data.list.splice(index + 1);
      console.log(item.children);
      data.list.push(
        item.children.map((e) => {
          return {
            ...e,
            selected: false,
            isShow: false,
            keywords: "",
            searchList: [],
          };
        })
      );
    } else {
      // 完成选择
      emits("finish");
    }
  } else {
    arr.map((e: any) => (e.selected = false));
    if (index !== undefined && index >= 0) {
      allList.value[index] = true;
      // 清空相关值和菜单
      const values = [...props.modelValue].filter((e) => e);
      values.splice(index);
      data.list?.splice(index + 1)
      setModelValue(values);
      // 完成选择
      emits("finish");
    }
  }
};

defineExpose({
  clearItem,
});
</script>

<style lang="scss" scoped>
.grid-select {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;

  &.search-select {
    margin-bottom: 12px;
  }

  .option {
    width: 30%;
    display: flex;
    align-items: center;
    text-align: center;
    justify-content: center;
    height: 40px;
    border-radius: 4px;
    padding: 0 4px;
    font-size: 13px;
    font-weight: 400;
    color: #3b3944;
    background: #f6f7f9;
    overflow: hidden;
    box-sizing: border-box;

    &.selected {
      background: #ffc8c7;
      color: #bb3d34;
    }
  }
}
.empty {
  text-align: center;
  margin-bottom: 20px;
  .image {
    width: 99px;
    height: 99px;
  }
  .text {
    display: flex;
    justify-content: center;
    font-size: 12px;
    color: #696969;
    white-space: nowrap;
    overflow: hidden;
    .keywords {
      color: #fdab27;
      text-overflow: ellipsis;
    }
  }
}
.search {
  font-size: 10px;
  color: #3b3944;
  background: #f8f9fb;
  border-radius: 50px;
  border: 1px solid #f0f0f0;
  padding: 0 10px;
  height: 56rpx;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  .icon {
    width: 15px;
    height: 15px;
  }
  .search-input {
    flex: 1;
    height: 100%;
  }
}
.isred {
  color: #fe4644 !important;
}
.value {
  font-size: 12px;
  font-weight: 400;
  color: #999999;
}
.iconfont {
  width: 24rpx;
  height: 24rpx;
}
.server-cascader {
  overflow: hidden;
  width: 100%;

  .menu {
    .item {
      height: 40px;
      font-size: 13px;
      font-weight: 400;
      color: #3b3944;
      padding: 0 0px;
      display: flex;
      align-items: center;
      overflow: hidden;
      display: flex;
      justify-content: space-between;

      &.selected {
        background: #fff;
        font-weight: 500;
      }
      .title {
        font-weight: 600;
        color: #000;
      }

      .text {
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }
    }
  }
  .content {
    width: 100%;
    padding: 0 0px;

    .list {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      gap: 8px;
      padding-bottom: 8px;
      .item {
        display: flex;
        align-items: center;
        text-align: center;
        justify-content: center;

        height: 40px;
        border-radius: 4px;
        padding: 0 4px;
        font-size: 13px;
        font-weight: 400;
        color: #3b3944;
        background: #f6f7f9;
        overflow: hidden;
        box-sizing: border-box;

        .text {
          text-overflow: ellipsis;
          display: -webkit-box;
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
        }

        &.selected {
          color: #bb3d34;
          background: #ffc8c7;
        }
      }
    }
  }
}
</style>
